/*
 *  Copyright 2007 Blandware (http://www.blandware.com)
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.blandware.atleap.persistence.hibernate.core;

import com.blandware.atleap.persistence.core.TileContainerDAO;
import com.blandware.atleap.model.core.TileContainer;
import com.blandware.atleap.model.core.Layout;
import com.blandware.atleap.common.util.PartialCollection;
import com.blandware.atleap.common.util.QueryInfo;
import com.blandware.atleap.common.Constants;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>Hibernate implementation of TileContainerDAO.</p>
 * <p><a href="TileContainerDAOHibernate.java.html"><i>View source</i></a></p>
 *
 * @author Roman Puchkovskiy <a href="mailto:roman.puchkovskiy@blandware.com">
 *         &lt;roman.puchkovskiy@blandware.com&gt;</a>
 * @version $Revision: 1.3 $ $Date: 2008/06/23 13:24:54 $
 */
public class TileContainerDAOHibernate extends BaseDAOHibernate
        implements TileContainerDAO {
    /**
     * Creates new instance of TileContainerDAOHibernate
     */
    public TileContainerDAOHibernate() {
    }

    /**
     * @see com.blandware.atleap.persistence.core.TileContainerDAO#createTileContainer(com.blandware.atleap.model.core.TileContainer, com.blandware.atleap.model.core.Layout)
     */
    public Long createTileContainer(TileContainer container, Layout layout) {
        container.setLayout(layout);
        return (Long) getHibernateTemplate().save(container);
    }

    /**
     * @see com.blandware.atleap.persistence.core.TileContainerDAO#retrieveTileContainer(Long)
     */
    public TileContainer retrieveTileContainer(Long id) {
        return (TileContainer) getHibernateTemplate().get(TileContainer.class,
                                                          id);
    }

    /**
     * @see com.blandware.atleap.persistence.core.TileContainerDAO#updateTileContainer(com.blandware.atleap.model.core.TileContainer) 
     */
    public void updateTileContainer(TileContainer tileContainer) {
        getHibernateTemplate().update(tileContainer);
    }

    /**
     * @see com.blandware.atleap.persistence.core.TileContainerDAO#deleteTileContainer(com.blandware.atleap.model.core.TileContainer)
     */
    public void deleteTileContainer(TileContainer container) {
        getHibernateTemplate().delete(container);
    }

    /**
     * @see com.blandware.atleap.persistence.core.TileContainerDAO#listTileContainers(com.blandware.atleap.common.util.QueryInfo)
     */
    public PartialCollection listTileContainers(QueryInfo queryInfo) {
        String whereClause = new String();
        String orderByClause = new String();
        if ( queryInfo != null ) {
            whereClause = queryInfo.getWhereClause();
            orderByClause = queryInfo.getOrderByClause();
            if ( whereClause == null ) {
                whereClause = new String();
            }
            if ( orderByClause != null && orderByClause.length() != 0 ) {
                orderByClause = " order by " + orderByClause;
            } else {
                orderByClause = "";
            }
        }

        ArrayList args = new ArrayList();

        List list = null;
        Integer total = null;
        String hqlPart = "from TileContainer c" + whereClause;
        if ( queryInfo != null && (queryInfo.getLimit() != null
                || queryInfo.getOffset() != null) ) {
            String hqlForTotal = "select count(distinct c.id) " + hqlPart;
            total = findUniqueIntegerResult(hqlForTotal, args.toArray());
            if ( total == null ) {
                total = new Integer(0);
            }
        }
        // If we don't have any info about the total number of results yet or
        // we know that there's something that will be found, then fetch data
        if ( total == null || total.intValue() > 0 ) {
            String hql = "select c " + hqlPart + orderByClause;
            list = executeFind(hql, queryInfo, args.toArray());
            if ( total == null ) {
                total = new Integer(list.size());
            }
        } else {
            list = new ArrayList();
        }
        return new PartialCollection(list, total);
    }

    /**
     * @see com.blandware.atleap.persistence.core.TileContainerDAO#hasDuplicates(com.blandware.atleap.model.core.TileContainer) 
     */
    public boolean hasDuplicates(TileContainer tileContainer) {

        ArrayList args = new ArrayList();
        args.add(tileContainer.getDefinitionName());
        args.add(tileContainer.getListName());

        String hql = "select count(c.id) from TileContainer c where c.definitionName = ? and c.listName = ?";
        if ( tileContainer.getId() != null ) {
            hql += " and c.id != ?";
            args.add(tileContainer.getId());
        }

        int count = (findUniqueIntegerResult(hql, args.toArray())).intValue();

        return count > 0;
    }

    /**
     * @see com.blandware.atleap.persistence.core.TileContainerDAO#findTileContainersByLayoutId(Long) 
     */
    public List findTileContainersByLayoutId(Long layoutId) {
        String hql = new StringBuffer("select c from TileContainer c where ")
                .append("c.layout.id = ?").toString();
        return executeFind(hql, new Object[]{layoutId});
    }

    /**
     * @see com.blandware.atleap.persistence.core.TileContainerDAO#findTileContainerByLayoutIdAndIdentifier(Long, String) 
     */
    public TileContainer findTileContainerByLayoutIdAndIdentifier(Long layoutId,
            String identifier) {
        int index = identifier.indexOf(Constants.TILE_CONTAINER_IDENTIFIER_SEPARATOR);
        if (index == -1) {
            return null;
        }
        String name = identifier.substring(0, index);
        String listName = identifier.substring(index + 1);
        String hql = new StringBuffer("select c from TileContainer c where ")
                .append("c.layout.id = ? and c.definitionName = ? ")
                .append("c.listName = ?").toString();
        return (TileContainer) findUniqueResult(hql,
                new Object[]{layoutId, name, listName});
    }
}
